/*
 * Copyright (C) 2013 gujicheng
 * 
 * Licensed under the GPL License Version 2.0;
 * you may not use this file except in compliance with the License.
 * 
 * If you have any question, please contact me.
 * 
 *************************************************************************
 **                   Author information                                **
 *************************************************************************
 ** Email: gujicheng197@126.com                                         **
 ** QQ   : 29600731                                                     **
 ** Weibo: http://weibo.com/gujicheng197                                **
 *************************************************************************
 */
package com.libra.sinvoice

import android.media.AudioManager
import android.media.AudioTrack

import com.libra.sinvoice.Buffer.BufferData

/**
 *
 * @ClassName: com.libra.sinvoice.PcmPlayer
 * @Description: PCM播放器
 * @author zhaokaiqiang
 * @date 2014-11-15 下午1:10:18
 */
class PcmPlayer(private val playerCallback: PcmCallback?, sampleRate: Int, channel: Int,
                format: Int, bufferSize: Int) {
    // 播放状态，用于控制播放或者是停止
    private var mState: Int = 0
    private val audioTrack: AudioTrack?
    // 已经播放过的字节长度
    private var playedLen: Long = 0
    private var pcmListener: PcmListener? = null

    interface PcmListener {

        fun onPcmPlayStart()

        fun onPcmPlayStop()
    }

    interface PcmCallback {

        fun getPcmPlayBuffer(): BufferData?

        fun freePcmPlayData(data: BufferData)
    }

    init {
        // 初始化AudioTrack对象(音频流类型，采样率，通道，格式，缓冲区大小，模式)
        audioTrack = AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                channel, format, bufferSize, AudioTrack.MODE_STREAM)
        mState = STATE_STOP
    }

    fun setListener(listener: PcmListener) {
        pcmListener = listener
    }

    fun start() {

        if (STATE_STOP == mState && null != audioTrack) {
            mState = STATE_START
            playedLen = 0

            if (null != playerCallback) {

                if (null != pcmListener) {
                    pcmListener!!.onPcmPlayStart()
                }
                while (STATE_START == mState) {
                    // 获取要播放的字节数据
                    val data = playerCallback.getPcmPlayBuffer()

                    if (null != data) {
                        if (null != data.byteData) {

                            // 首次进入，开始播放声音
                            if (0L == playedLen) {
                                audioTrack.play()
                            }

                            // 设置要播放的字节数据
                            val len = audioTrack.write(data.byteData, 0,
                                    data.filledSize)

                            playedLen += len.toLong()
                            // 释放数据
                            playerCallback.freePcmPlayData(data)
                        } else {
                            LogHelper.d(TAG,
                                    "it is the end of input, so need stop")
                            break
                        }
                    } else {
                        LogHelper.d(TAG, "get null data")
                        break
                    }

                }

                if (STATE_STOP == mState) {
                    audioTrack.pause()
                    audioTrack.flush()
                    audioTrack.stop()
                    audioTrack.release()
                }
                if (null != pcmListener) {
                    pcmListener!!.onPcmPlayStop()
                }
            } else {
                throw IllegalArgumentException("PcmCallback can't be null")
            }
        }
    }

    fun stop() {
        if (STATE_START == mState && null != audioTrack) {
            mState = STATE_STOP
        }
    }

    companion object {

        private val TAG = "PcmPlayer"
        private val STATE_START = 1
        private val STATE_STOP = 2
    }
}
